package com.onlineMIS.ORM.DAO.headQ.supplier.supplierMgmt;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.onlineMIS.ORM.DAO.Response;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQEntityTagDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQTagDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQTagGroupDaoImpl;
import com.onlineMIS.ORM.entity.base.Pager;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadQTag;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadqEntityTag;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCust;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCustVO;
import com.onlineMIS.ORM.entity.headQ.finance.ChainAcctFlowReportItem;
import com.onlineMIS.ORM.entity.headQ.finance.ChainAcctFlowTemplate;
import com.onlineMIS.ORM.entity.headQ.supplier.supplierMgmt.HeadQSupplier;
import com.onlineMIS.ORM.entity.headQ.supplier.supplierMgmt.HeadQSupplierTemplate;
import com.onlineMIS.ORM.entity.headQ.supplier.supplierMgmt.HeadQSupplierVO;
import com.onlineMIS.action.headQ.supplier.supplierMgmt.HeadQSupplierMgmtFormBean;
import com.onlineMIS.common.Common_util;
import com.onlineMIS.common.ExcelUtil;
import com.onlineMIS.common.StrCheckUtils;
import com.onlineMIS.common.loggerLocal;

@Service
public class HeadQSupplierService {
	
	@Autowired
	private HeadQSupplierDaoImpl headQSupplierDaoImpl;
	@Autowired
	private HeadQEntityTagDaoImpl headQEntityTagDaoImpl;
	@Autowired
	private HeadQTagDaoImpl headQTagDaoImpl;

	/**
	 * 获取当前页所有客户的信息
	 * 
	 * @param uiBean
	 * @param basicData
	 */
	public Response listSupplier(HeadQSupplier supplier, Integer page, Integer rowPerPage, String sort,
			String sortOrder) {
		Response response = new Response();
		Map dataMap = new HashMap();

		// 获取总条数的 criteria
		DetachedCriteria custTotalCriteria = DetachedCriteria.forClass(HeadQSupplier.class);
		// 获取list的 criteria
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQSupplier.class);

		if (supplier != null) {
			String custName = StringUtils.trim(supplier.getName());
			if (StringUtils.isNotEmpty(custName)) {
				custTotalCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}

			String pinyin = StringUtils.trim(supplier.getPinyin());
			if (StringUtils.isNotEmpty(pinyin)) {
				custCriteria.add(Restrictions.like("pinyin", pinyin, MatchMode.ANYWHERE));
				custTotalCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}
		}

		// 1. 获取总条数
		custTotalCriteria.setProjection(Projections.rowCount());
		int total = Common_util
				.getProjectionSingleValue(headQSupplierDaoImpl.getByCriteriaProjection(custTotalCriteria, true));

		// 2. 获取当页数据
		if (sortOrder.equalsIgnoreCase("asc"))
			custCriteria.addOrder(Order.asc(sort));
		else
			custCriteria.addOrder(Order.desc(sort));
		List<HeadQSupplier> suppliers = headQSupplierDaoImpl.getByCritera(custCriteria,
				Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);

		dataMap.put("rows", suppliers);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	/**
	 * 在单据上搜索供应商信息，需要自动过滤status 不正常客户
	 * 
	 * @param cust
	 * @return
	 */
	public Response searchSuppliers(HeadQSupplier supplier) {
		Response response = new Response();

		// 获取list的 criteria
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQSupplier.class);

		custCriteria.add(Restrictions.eq("status", HeadQSupplier.CustStatusEnum.GOOD.getKey()));

		if (supplier != null) {
			String pinyin = StringUtils.trim(supplier.getPinyin());
			if (StringUtils.isNotEmpty(pinyin)) {
				custCriteria.add(Restrictions.like("pinyin", pinyin, MatchMode.ANYWHERE));
			}

			String custName = StringUtils.trim(supplier.getName());
			if (StringUtils.isNotEmpty(custName)) {
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}
		}

		// 2. 获取当页数据
		custCriteria.addOrder(Order.asc("status"));
		custCriteria.addOrder(Order.asc("pinyin"));
		List<HeadQSupplier> custs = headQSupplierDaoImpl.getByCritera(custCriteria, true);

		Map data = new HashMap<String, List>();
		data.put("rows", custs);
		data.put("footer", null);
		response.setReturnValue(data);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	/**
	 * 更新或者创建的客户信息
	 * 
	 * @param headQCust
	 * @return
	 */
	public Response createOrUpdateSupplier(HeadQSupplier supplier) {
		Response response = new Response();

		try {
			// 创建新的
			if (supplier.getId() == 0) {
				supplier.setPinyin(Common_util.getPinyinCode(supplier.getName(), false));
				headQSupplierDaoImpl.save(supplier, true);
				response.setSuccess("成功创建新的客户");
			} else {
				// 更新旧的客户信息
				HeadQSupplier headQCust2 = headQSupplierDaoImpl.get(supplier.getId(), true);
				if (headQCust2 == null) {
					response.setFail("查找原客户信息失败 : 查找Id " + supplier.getId());
				} else {
					headQCust2.copyInforFromOther(supplier);
					headQCust2.setPinyin(Common_util.getPinyinCode(headQCust2.getName(), false));
					headQSupplierDaoImpl.saveOrUpdate(headQCust2, true);
					response.setSuccess("成功更新客户信息");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setFail("更新客户信息失败 : " + e.getMessage());
		}

		return response;
	}

	/**
	 * 冻结客户信息
	 * 
	 * @param custId
	 * @return
	 */
	public Response disableSupplier(int supplierId) {
		Response response = new Response();
		String hql = "UPDATE HeadQSupplier SET status = ? WHERE id = ?";
		try {
			Object[] values = { HeadQCust.CustStatusEnum.DELETED.getKey(), supplierId };

			int record = headQSupplierDaoImpl.executeHQLUpdateDelete(hql, values, true);
			if (record == 1)
				response.setSuccess("成功冻结客户数据");
			else
				response.setSuccess("冻结客户数据失败");
		} catch (Exception e) {
			response.setFail("冻结客户信息失败 : " + e.getMessage());
		}

		return response;
	}

	/**
	 * 准备修改或者添加某个客户时
	 * 
	 * @param cust
	 */
	public Response preEditSupplier(HeadQSupplier supplier) {
		Response response = new Response();

		// 当前是添加新客户
		if (supplier == null || supplier.getId() == 0) {
			return response;
		} else {
			int id = supplier.getId();
			HeadQSupplier cust2 = headQSupplierDaoImpl.get(id, true);
			if (cust2 != null) {
				response.setReturnValue(cust2);
				return response;
			} else {
				response.setFail("无法获取客户信息 : " + id);
				return response;
			}
		}

	}

	/**
	 * 导出供应商信息
	 * 
	 * @param path
	 * @param formBean
	 * @return
	 */
	public Response generateHeadSupplierExcel(String path, HeadQSupplierMgmtFormBean formBean) {
		Response response = new Response();
		List<HeadQSupplierVO> supplierVOs = new ArrayList<HeadQSupplierVO>();
		List<HeadQSupplier> list = new ArrayList<HeadQSupplier>();
		Set<Integer> supplierIdSet = new HashSet<Integer>();
		int tagId = formBean.getTagId();
		String name = formBean.getSupplierName();
		try {
			if (tagId != 0 || StringUtils.isNotBlank(name)) {
				List<HeadqEntityTag> entityTags = headQEntityTagDaoImpl.getEntityTagByTagId(tagId);
				for (HeadqEntityTag entityTag : entityTags) {
					supplierIdSet.add(entityTag.getEntityId());
				}
				DetachedCriteria criteria2 = buildSupplierTagCriteria(name, supplierIdSet);
				list = headQSupplierDaoImpl.getByCritera(criteria2, true);
			} else {
				list = headQSupplierDaoImpl.getAllSuppliers();
			}
			supplierVOs = getSupplierVos(list);
			HeadQSupplierTemplate template = new HeadQSupplierTemplate(path, supplierVOs);

			HSSFWorkbook wb = template.process();
			ByteArrayInputStream byteArrayInputStream = ExcelUtil.convertExcelToInputStream(wb);

			response.setReturnValue(byteArrayInputStream);
			response.setReturnCode(Response.SUCCESS);
		} catch (Exception e) {
			loggerLocal.error(e);
			e.printStackTrace();
			response.setFail(e.getMessage());
		}
		return response;
	}

	/**
	 * 分页查询供应商信息
	 * 
	 * @param name
	 * @param tagId
	 * @param supplier
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param sortOrder
	 * @return
	 */
	public Response listSupplierTag(String name, int tagId, HeadQSupplier supplier, Integer page, Integer rowPerPage,
			String sort, String sortOrder) {
		Response response = new Response();
		Map dataMap = new HashMap();
		List<HeadQSupplierVO> supplierVOs = new ArrayList<HeadQSupplierVO>();
		int total = 0;
		// 条件查询

		Set<Integer> supplierIdSet = new HashSet<Integer>();
		if (tagId != 0) {
			List<HeadqEntityTag> entityTags = headQEntityTagDaoImpl.getEntityTagByTagId(tagId);
			for (HeadqEntityTag entityTag : entityTags)
				supplierIdSet.add(entityTag.getEntityId());
			// 1. 获取总条数
			DetachedCriteria criteria = buildSupplierTagCriteria(name, supplierIdSet);
			criteria.setProjection(Projections.rowCount());
			total = Common_util.getProjectionSingleValue(headQSupplierDaoImpl.getByCriteriaProjection(criteria, true));

			// 2.获取明细
			DetachedCriteria criteria2 = buildSupplierTagCriteria(name, supplierIdSet);
			List<HeadQSupplier> suppliers = headQSupplierDaoImpl.getByCritera(criteria2,
					Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);

			// 3.创建vo
			supplierVOs = getSupplierVos(suppliers);

		} else {
			// 获取总条数的 criteria
			DetachedCriteria custTotalCriteria = buildSupplierTagCriteria(name, supplierIdSet);
			// 获取list的 criteria
			DetachedCriteria custCriteria = buildSupplierTagCriteria(name, supplierIdSet);
			// 1. 获取总条数
			custTotalCriteria.setProjection(Projections.rowCount());
			total = Common_util.getProjectionSingleValue(headQSupplierDaoImpl.getByCriteriaProjection(custTotalCriteria, true));

			// 2. 获取当页数据
			if (sortOrder.equalsIgnoreCase("asc")) {
				custCriteria.addOrder(Order.asc(sort));
			}else {
				custCriteria.addOrder(Order.desc(sort));
			}
								
			List<HeadQSupplier> suppliers = headQSupplierDaoImpl.getByCritera(custCriteria,Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);
			supplierVOs = getSupplierVos(suppliers);
		}

		dataMap.put("rows", supplierVOs);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	/**
	 * 条件查询
	 * 
	 * @param name
	 * @param tagId
	 * @return
	 */
	private DetachedCriteria buildSupplierTagCriteria(String name, Set<Integer> supplierIdSet) {
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadQSupplier.class);

		if (name != null && name != "") {
			Pattern pattern = Pattern.compile("[A-Za-z]*");
			Matcher isNum = pattern.matcher(name);

			if (isNum.matches()) {
				criteria.add(Restrictions.like("pinyin", name, MatchMode.ANYWHERE));
			} else {
				criteria.add(Restrictions.like("name", name, MatchMode.ANYWHERE));
			}
		}
		if (supplierIdSet.size() > 0) {
			criteria.add(Restrictions.in("id", supplierIdSet));
		}
		criteria.addOrder(Order.desc("id"));
		return criteria;
	}

	
	/**
	 * 封装供应商VO信息
	 * @param list
	 * @return
	 */
	public List<HeadQSupplierVO> getSupplierVos(List<HeadQSupplier> list) {

		List<HeadQSupplierVO> hVos = new ArrayList<HeadQSupplierVO>();
		if (list.size() > 0) {
			for (HeadQSupplier headQSupplier : list) {
				// 获取供应商的所有tag_id
				List<Integer> tagIds = headQEntityTagDaoImpl.selectTagsBySupplierId(headQSupplier.getId());
				List<HeadQTag> headQTags = headQTagDaoImpl.selectByIds(tagIds);
				String tags = "";
				if (headQTags != null) {
					for (int i = 0; i < headQTags.size(); i++) {
						if (i == headQTags.size() - 1) {
							tags += headQTags.get(i).getTagName();
						} else {
							tags += headQTags.get(i).getTagName() + ",";
						}
					}
				}
				HeadQSupplierVO hVo = new HeadQSupplierVO(headQSupplier.getId(), headQSupplier.getName(),
						headQSupplier.getPhone(), headQSupplier.getAddress(), headQSupplier.getInitialAcctBalance(),
						headQSupplier.getCurrentAcctBalance(), headQSupplier.getComment(), headQSupplier.getPinyin(),
						tags, headQSupplier.getStatus());
				hVos.add(hVo);
			}

		}

		return hVos;
	}

	
	/**
	 * 分页查询供应商信息
	 * @param formBean
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param sortOrder
	 * @return
	 */
	public Response selectSupplierVosByPage(HeadQSupplierMgmtFormBean formBean, Integer page, Integer rowPerPage, String sort,
			String sortOrder) {
		Response response = new Response();
		Map dataMap = new HashMap();
		int total = 0;
		// 条件查询

		// 获取总条数的 criteria
		DetachedCriteria custTotalCriteria = DetachedCriteria.forClass(HeadQSupplier.class);
		// 获取list的 criteria
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQSupplier.class);

		String custName = StringUtils.trim(formBean.getOrder().getSupplier().getName());
		if (StringUtils.isNotEmpty(custName)) {
			if(StrCheckUtils.isLetter(custName)) {
				custTotalCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
				custCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
			}else {
				custTotalCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}

		}

		// 1. 获取总条数
		custTotalCriteria.setProjection(Projections.rowCount());
		total = Common_util.getProjectionSingleValue(headQSupplierDaoImpl.getByCriteriaProjection(custTotalCriteria, true));

		// 2. 获取当页数据
		List<HeadQSupplier> suppliers = headQSupplierDaoImpl.getByCritera(custCriteria,
				Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);

		//3. 添加所有供应商
		if (page == Pager.FIRST_PAGE && formBean.getIndicator() != 0){
			suppliers.add(0, HeadQSupplierDaoImpl.getAllSupplierObj());
		}
		
		List<HeadQSupplierVO> list =  getSupplierVos(suppliers);
		dataMap.put("rows", list);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}
	
	
	
	/**
	 * 分页查询供应商信息
	 * @param formBean
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param sortOrder
	 * @return
	 */
	public Response listSupplierByPage(HeadQSupplierMgmtFormBean formBean, Integer page, Integer rowPerPage, String sort,
			String sortOrder) {
		Response response = new Response();
		Map dataMap = new HashMap();
		int total = 0;
		// 条件查询

		// 获取总条数的 criteria
		DetachedCriteria custTotalCriteria = DetachedCriteria.forClass(HeadQSupplier.class);
		// 获取list的 criteria
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQSupplier.class);

		String custName = StringUtils.trim(formBean.getOrder().getSupplier().getName());
		if (StringUtils.isNotEmpty(custName)) {
			if(StrCheckUtils.isLetter(custName)) {
				custTotalCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
				custCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
			}else {
				custTotalCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}

		}

		// 1. 获取总条数
		custTotalCriteria.setProjection(Projections.rowCount());
		total = Common_util.getProjectionSingleValue(headQSupplierDaoImpl.getByCriteriaProjection(custTotalCriteria, true));

		// 2. 获取当页数据
		List<HeadQSupplier> suppliers = headQSupplierDaoImpl.getByCritera(custCriteria,
				Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);

		//3. 添加所有供应商
		if (page == Pager.FIRST_PAGE && formBean.getIndicator() != 0){
			suppliers.add(0, HeadQSupplierDaoImpl.getAllSupplierObj());
		}
		
		dataMap.put("rows", suppliers);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

}
